import { Injectable, Logger } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { SecurityLogService } from '../services/security-log.service';
import { SecurityEventEmitter, SecurityEventPayload } from '../events/security-event.emitter';
import { CreateSecurityLogDto } from '../dto/create-security-log.dto';

@Injectable()
export class SecurityEventListener {
  private readonly logger = new Logger(SecurityEventListener.name);

  constructor(private readonly securityLogService: SecurityLogService) {}

  /**
   * 处理认证成功事件
   */
  @OnEvent('security.auth.success')
  async handleAuthSuccess(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`认证成功事件已记录: ${payload.username}`);
    } catch (error) {
      this.logger.error(`记录认证成功事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理认证失败事件
   */
  @OnEvent('security.auth.failed')
  async handleAuthFailed(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
        errorMessage: payload.errorMessage,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`认证失败事件已记录: ${payload.username}`);
    } catch (error) {
      this.logger.error(`记录认证失败事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理未授权访问事件
   */
  @OnEvent('security.unauthorized.access')
  async handleUnauthorizedAccess(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`未授权访问事件已记录: ${payload.username || 'anonymous'}`);
    } catch (error) {
      this.logger.error(`记录未授权访问事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理权限拒绝事件
   */
  @OnEvent('security.permission.denied')
  async handlePermissionDenied(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`权限拒绝事件已记录: ${payload.username}`);
    } catch (error) {
      this.logger.error(`记录权限拒绝事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理验证错误事件
   */
  @OnEvent('security.validation.error')
  async handleValidationError(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
        errorMessage: payload.errorMessage,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`验证错误事件已记录: ${payload.username || 'anonymous'}`);
    } catch (error) {
      this.logger.error(`记录验证错误事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理业务错误事件
   */
  @OnEvent('security.business.error')
  async handleBusinessError(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
        errorMessage: payload.errorMessage,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`业务错误事件已记录: ${payload.username || 'anonymous'}`);
    } catch (error) {
      this.logger.error(`记录业务错误事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理系统错误事件
   */
  @OnEvent('security.system.error')
  async handleSystemError(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
        errorMessage: payload.errorMessage,
        stackTrace: payload.stackTrace,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`系统错误事件已记录: ${payload.username || 'anonymous'}`);
    } catch (error) {
      this.logger.error(`记录系统错误事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理可疑活动事件
   */
  @OnEvent('security.suspicious.activity')
  async handleSuspiciousActivity(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`可疑活动事件已记录: ${payload.username || 'anonymous'}`);
    } catch (error) {
      this.logger.error(`记录可疑活动事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理频率限制事件
   */
  @OnEvent('security.rate.limit.exceeded')
  async handleRateLimitExceeded(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`频率限制事件已记录: ${payload.username || 'anonymous'}`);
    } catch (error) {
      this.logger.error(`记录频率限制事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理SQL注入尝试事件
   */
  @OnEvent('security.sql.injection.attempt')
  async handleSqlInjectionAttempt(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`SQL注入尝试事件已记录: ${payload.username || 'anonymous'}`);
    } catch (error) {
      this.logger.error(`记录SQL注入尝试事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理XSS尝试事件
   */
  @OnEvent('security.xss.attempt')
  async handleXssAttempt(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`XSS尝试事件已记录: ${payload.username || 'anonymous'}`);
    } catch (error) {
      this.logger.error(`记录XSS尝试事件失败: ${error.message}`, error.stack);
    }
  }

  /**
   * 处理自定义安全事件
   */
  @OnEvent('security.custom.event')
  async handleCustomEvent(payload: SecurityEventPayload) {
    try {
      const createDto: CreateSecurityLogDto = {
        eventType: payload.eventType,
        securityLevel: payload.securityLevel,
        eventTitle: payload.eventTitle,
        eventDescription: payload.eventDescription,
        userId: payload.userId,
        username: payload.username,
        ipAddress: payload.ipAddress,
        userAgent: payload.userAgent,
        requestUrl: payload.requestUrl,
        requestMethod: payload.requestMethod,
        requestParams: payload.additionalInfo,
        errorMessage: payload.errorMessage,
        stackTrace: payload.stackTrace,
      };

      await this.securityLogService.createSecurityLog(createDto);
      this.logger.debug(`自定义安全事件已记录: ${payload.eventTitle}`);
    } catch (error) {
      this.logger.error(`记录自定义安全事件失败: ${error.message}`, error.stack);
    }
  }
}
